package com.code.user.client;

import com.code.AZPlan.model.bo.UserVipBO;
import com.code.commons.constants.ServerConstants;
import com.code.commons.service.RestfulCrudService;
import com.code.user.client.hystrix.UserClientHystrix;
import com.code.user.model.bo.*;
import com.code.user.model.po.*;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 暴露的用户相关的restful风格的api
 *
 * @author tangyifei
 * @since 2019-5-24 09:31:13
 */
@FeignClient(value = ServerConstants.USER, path = "users", fallback = UserClientHystrix.class)
public interface UserClient extends RestfulCrudService<User, String> {

    /**
     * 根据用户主键获取用户的凭证信息
     *
     * @param userId 关联的用户主键
     * @return 用户信息
     */
    @GetMapping("/credential/{userId}")
    User getUserCredential(@PathVariable("userId") String userId);

    /**
     * 根据手机号查询用户主键
     *
     * @param userPhone 用户手机号
     * @return 用户主键
     */
    @GetMapping("/{userPhone}/phone-is-exist")
    Boolean judgeUserPhoneIsExist(@PathVariable("userPhone") String userPhone);

    /**
     * 根据邮箱查询用户主键
     *
     * @param userEmail 用户邮箱
     * @return 用户主键
     */
    @GetMapping("/{userEmail}/email-is-exist")
    Boolean judgeUserEmailIsExist(@PathVariable("userEmail") String userEmail);

    /**
     * 注册用户
     *
     * @param registerUser 注册用户对象
     * @return 添加成功的用户
     */
    @PostMapping("/register")
    User registerUser(@RequestBody RegisterUser registerUser);

    /**
     * 通过手机号查询用户信息
     *
     * @param userPhone 注册用户手机号
     * @return 添加成功的用户信息
     */
    @GetMapping("/{userPhone}/user-detail")
    LoginUserCredential getUserByPhone(@PathVariable("userPhone") String userPhone);

    /**
     * 重置密码
     *
     * @param userId 用户主键
     * @param newPwd 用户新密码
     */
    @PatchMapping("/reset-pwd")
    void resetPwd(@RequestParam("userId") String userId, @RequestParam("newPwd") String newPwd);

    /**
     * 更新用户相关的币种余额信息(增加币种余额)
     *
     * @param userCoinBalance 币种余额信息表
     */
    @PatchMapping("/add-user-coin-balance")
    int addCoinBalance(@RequestBody UserCoinBalance userCoinBalance) throws Exception;

    /**
     * 更新用户相关的币种地址
     *
     * @param userCoinBalance 币种余额信息表
     */
    @PatchMapping("/update-user-coin-address")
    void updateUserCoinAddress(@RequestBody UserCoinBalance userCoinBalance) throws Exception;

    /**
     * 获取某一个用户的入金通道列表
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     * @return 入金通道列表
     */
    @GetMapping("/{userId}/AZPlanChannels")
    List<UserAZPlanChannel> getAZPlanChannelList(@PathVariable("userId") String userId, @RequestParam("coinType") String coinType);

    /**
     * 用户内部充值
     *
     * @param rechargeTranRecord 用户充值对象
     * @return 影响的行数
     */
    @PostMapping("/inner-recharge")
    int recharge(@RequestBody RechargeTranRecord rechargeTranRecord);

    /**
     * 获取用户相关的币种余额信息
     *
     * @param userId      用户主键
     * @param coinType    币种类型
     * @param coinAddress 币种地址
     */
    @GetMapping("/get-user-coin-balance")
    UserCoinBalance getUserCoinBalance(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType,
                                       @RequestParam(value = "coinAddress", required = false) String coinAddress);

    /**
     * 获取用户相关的币种地址
     *
     * @param userId   用户主键
     * @param coinType 币种类型
     */
    @GetMapping("/get-user-coin-address")
    String getUserCoinAddressByUserId(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType);

    /**
     * 通过用户主键、币种地址、币种类型获取已经同步的充值总金额
     *
     * @param userId      用户主键
     * @param coinType    币种类型
     * @param coinAddress 币种地址
     */
    @GetMapping("/get-total-recharge-amount")
    BigDecimal getTotalRechargeAmount(@RequestParam("userId") String userId, @RequestParam("coinType") String coinType,
                                      @RequestParam("coinAddress") String coinAddress);

    /**
     * 跳转邀请用户注册页面获取推荐人矿池的当前版本号和USDT钱包的账户版本号
     *
     * @param recommenderPhone 推荐人的手机号
     * @return 推荐人矿池的当前版本号和USDT钱包的账户版本号
     */
    @GetMapping("/{recommenderPhone}/get-usdt-version")
    UserCoinBalanceBO getUsdtVersion(@PathVariable("recommenderPhone") String recommenderPhone);

    /**
     * 手机号与tokenID绑定
     *
     * @param mobilePhone 手机号
     * @param tokenId     token主键
     */
    @PostMapping("/{mobilePhone}/token")
    void bindingUserTokenAndUserPhone(@PathVariable("mobilePhone") String mobilePhone, @RequestParam("tokenId") String tokenId);

    /**
     * 根据手机号获取tokenId
     *
     * @param userVipBOS vip列表
     * @return token对象列表
     */
    @GetMapping("/get-token-list")
    List<UserToken> getTokenList(@RequestBody List<UserVipBO> userVipBOS);

    /**
     * 通过币种类型获取钱包相关币种信息列表
     *
     * @param coinType 币种类型
     * @return 用户钱包相关币种信息列表
     */
    @GetMapping("/get-user-wallet—list")
    List<UserCoinBalance> getUserWalletList(@RequestParam("coinType") String coinType);

    /**
     * 扣减用户钱包金额
     *
     * @param userCoinBalance 用户钱包余额对象
     * @return 提币订单列表
     */
    @PatchMapping("/wallets/reduce-user-coin-balance")
    int reduceUserCoinBalance(@RequestBody UserCoinBalance userCoinBalance);

    /**
     * 根据用户主键获取推荐人的直推用户列表
     *
     * @param userId   用户主键
     * @param page     当前页
     * @param pageSize 每页的大小
     * @return 推荐人的直推用户列表
     */
    @GetMapping("/{userId}/directRecommends")
    Map<String, Object> getDirectRecommends(@PathVariable("userId") String userId,
                                            @RequestParam(value = "entryMoneyState", required = false) Integer entryMoneyState,
                                            @RequestParam(value = "page", required = false) Integer page,
                                            @RequestParam(value = "pageSize", required = false) Integer pageSize);

    /**
     * 根据用户手机号获取用户登录token
     *
     * @param mobilePhone 用户手机号
     * @return 用户登录token
     */
    @GetMapping("/{mobilePhone}/get-token")
    String getUserTokenByUserPhone(@PathVariable("mobilePhone") String mobilePhone);

    /**
     * 提交用户认证
     *
     * @param userCertification 用户认证对象
     * @return 影响的行数
     */
    @PostMapping("/user-certifications")
    int addUserCertification(@RequestBody UserCertification userCertification);

    /**
     * 获取用户认证详情
     *
     * @param userId 用户主键
     * @return 用户认证详情
     */
    @GetMapping("/{userId}/user-certifications")
    UserCertification getUserCertificationByUserId(@PathVariable("userId") String userId);

    /**
     * 通过证件号码获取该证件号认证的用户个数
     *
     * @param certificationNumber 用户主键
     * @return 证件号认证的用户个数
     */
    @GetMapping("/{certificationNumber}/user-certifications-count")
    int getUserCertificationCountByCertificationNumber(@PathVariable("certificationNumber") String certificationNumber);

    /**
     * 获取用户认证列表
     *
     * @param userCertificationBO 用户认证查询对象
     * @return 用户认证列表
     */
    @PostMapping("/user-certification-list")
    UserCertificationBO getUserCertificationList(@RequestBody UserCertificationBO userCertificationBO);

    /**
     * 更新用户认证信息
     *
     * @param userCertification 用户认证对象
     * @return 影响的行数
     */
    @PatchMapping("/user-certifications")
    int updateUserCertification(@RequestBody UserCertification userCertification);

    /**
     * 更新系统维护开关
     *
     * @param systemSettingBO 系统维护业务对象
     * @return 影响的行数
     */
    @PatchMapping("/system-setting")
    int updateSystemSetting(@RequestBody SystemSettingBO systemSettingBO);

    /**
     * 获取系统信息
     *
     * @param systemKey 系统相关的key
     * @return 系统信息
     */
    @GetMapping("/{systemKey}/system-setting")
    SystemSettingBO getSystemSettingBySystemKey(@PathVariable("systemKey") String systemKey);

    /**
     * 获取某一个用户钱包列表
     *
     * @param userId 用户主键
     * @return 用户钱包列表
     */
    @GetMapping("/{userId}/get-user-wallet-list")
    List<UserCoinBalance> getUserCoinBalanceList(@PathVariable("userId") String userId);

    /**
     * 通过用户手机号的部分信息模糊查询用户手机
     *
     * @param phone 模糊查询的手机号
     * @return 手机号列表
     */
    @GetMapping("/get-user-phones")
    PhoneBO getUserPhones(@RequestParam(value = "phone", required = false) String phone,
                          @RequestParam(value = "page", required = false) Integer page,
                          @RequestParam(value = "pageSize", required = false) Integer pageSize);

    /**
     * 禁止或者取消用户的相关的操作
     *
     * @param userOperateAuth 用户操作权限PO及持久层对象
     * @return 影响的行数
     */
    @PostMapping("/set-user-operate")
    int setUserOperate(@RequestBody UserOperateAuth userOperateAuth);

    /**
     * 根据用户主键和操作码查询用户的操作权限
     *
     * @param userId      用户主键
     * @param operateCode 操作码
     * @return UserOperateAuth 用户操作权限PO及持久层对象
     */
    @GetMapping("/get-user-operate")
    UserOperateAuth getUserOperateAuthByUserIdAndOperateCode(@RequestParam String userId, @RequestParam String operateCode);

}
